#pragma once
#define INITGUID
#include <windows.h>
#include <CGuid.h>
//#include <initguid.h>
#include <atlbase.h>
#include <atlcom.h>
#include <ObjSafe.h>
#include "luascript_h.h"
#include "resource.h"
extern "C" {
	#include "lua.h"
	#include "lualib.h"
	#include "lauxlib.h"
}
#pragma comment(lib, "lua51.lib")

class ATL_NO_VTABLE LuaScript:
	public CComObjectRootEx<CComSingleThreadModel>,
	public CComCoClass<LuaScript, &CLSID_LuaScript>,
	public ILuaScript,
	public IActiveScript,
	public IActiveScriptParse,
	public IObjectSafety
{
public:
	LuaScript(void);
	virtual ~LuaScript(void);

DECLARE_REGISTRY_RESOURCEID(IDR_LUASCRIPT)
DECLARE_NOT_AGGREGATABLE(LuaScript)

DECLARE_PROTECT_FINAL_CONSTRUCT()

BEGIN_COM_MAP(LuaScript)
	COM_INTERFACE_ENTRY(ILuaScript)
	COM_INTERFACE_ENTRY(IActiveScript)
	COM_INTERFACE_ENTRY(IActiveScriptParse)
	COM_INTERFACE_ENTRY(IObjectSafety)
END_COM_MAP()
/*
BEGIN_CATEGORY_MAP(CActiveScript)
	IMPLEMENTED_CATEGORY(AXT_CATID_ActiveScript)
	IMPLEMENTED_CATEGORY(AXT_CATID_ActiveScriptParse)
END_CATEGORY_MAP()
*/
	// IActiveScript
    HRESULT STDMETHODCALLTYPE SetScriptSite( 
        /* [in] */ IActiveScriptSite __RPC_FAR *pass);
    
    HRESULT STDMETHODCALLTYPE GetScriptSite( 
        /* [in] */ REFIID riid,
        /* [iid_is][out] */ void __RPC_FAR *__RPC_FAR *ppvObject);
    
    HRESULT STDMETHODCALLTYPE SetScriptState( 
        /* [in] */ SCRIPTSTATE ss);
    
    HRESULT STDMETHODCALLTYPE GetScriptState( 
        /* [out] */ SCRIPTSTATE __RPC_FAR *pssState);
    
    HRESULT STDMETHODCALLTYPE Close( void);
    
    HRESULT STDMETHODCALLTYPE AddNamedItem( 
        /* [in] */ LPCOLESTR pstrName,
        /* [in] */ DWORD dwFlags);
    
    HRESULT STDMETHODCALLTYPE AddTypeLib( 
        /* [in] */ REFGUID rguidTypeLib,
        /* [in] */ DWORD dwMajor,
        /* [in] */ DWORD dwMinor,
        /* [in] */ DWORD dwFlags);
    
    HRESULT STDMETHODCALLTYPE GetScriptDispatch( 
        /* [in] */ LPCOLESTR pstrItemName,
        /* [out] */ IDispatch __RPC_FAR *__RPC_FAR *ppdisp);
    
    HRESULT STDMETHODCALLTYPE GetCurrentScriptThreadID( 
        /* [out] */ SCRIPTTHREADID __RPC_FAR *pstidThread);
    
    HRESULT STDMETHODCALLTYPE GetScriptThreadID( 
        /* [in] */ DWORD dwWin32ThreadId,
        /* [out] */ SCRIPTTHREADID __RPC_FAR *pstidThread);
    
    HRESULT STDMETHODCALLTYPE GetScriptThreadState( 
        /* [in] */ SCRIPTTHREADID stidThread,
        /* [out] */ SCRIPTTHREADSTATE __RPC_FAR *pstsState);
    
    HRESULT STDMETHODCALLTYPE InterruptScriptThread( 
        /* [in] */ SCRIPTTHREADID stidThread,
        /* [in] */ const EXCEPINFO __RPC_FAR *pexcepinfo,
        /* [in] */ DWORD dwFlags);
    
    HRESULT STDMETHODCALLTYPE Clone( 
        /* [out] */ IActiveScript __RPC_FAR *__RPC_FAR *ppscript);

	STDMETHOD(InitNew)(void);

	STDMETHOD(AddScriptlet)( 
            /* [in] */ LPCOLESTR pstrDefaultName,
            /* [in] */ LPCOLESTR pstrCode,
            /* [in] */ LPCOLESTR pstrItemName,
            /* [in] */ LPCOLESTR pstrSubItemName,
            /* [in] */ LPCOLESTR pstrEventName,
            /* [in] */ LPCOLESTR pstrDelimiter,
            /* [in] */ DWORD dwSourceContextCookie,
            /* [in] */ ULONG ulStartingLineNumber,
            /* [in] */ DWORD dwFlags,
            /* [out] */ BSTR *pbstrName,
            /* [out] */ EXCEPINFO *pexcepinfo);
        
	STDMETHOD(ParseScriptText)( 
            /* [in] */ LPCOLESTR pstrCode,
            /* [in] */ LPCOLESTR pstrItemName,
            /* [in] */ IUnknown *punkContext,
            /* [in] */ LPCOLESTR pstrDelimiter,
            /* [in] */ DWORD dwSourceContextCookie,
            /* [in] */ ULONG ulStartingLineNumber,
            /* [in] */ DWORD dwFlags,
            /* [out] */ VARIANT *pvarResult,
            /* [out] */ EXCEPINFO *pexcepinfo);

	// IObjectSafety
    STDMETHOD(GetInterfaceSafetyOptions)( 
            /* [in] */ REFIID riid,
            /* [out] */ DWORD *pdwSupportedOptions,
            /* [out] */ DWORD *pdwEnabledOptions);

	STDMETHOD(SetInterfaceSafetyOptions)( 
            /* [in] */ REFIID riid,
            /* [in] */ DWORD dwOptionSetMask,
            /* [in] */ DWORD dwEnabledOptions);

private:
	IActiveScriptSite* m_pass;
	lua_State *L;
	DWORD safetyOptions;
};
